package com.pabble.webnative;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.Rect;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.DownloadListener;
import android.webkit.WebResourceRequest;
import android.webkit.WebResourceResponse;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.ProgressBar;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.webkit.internal.AssetHelper;

import com.pabble.webnative.Interface.ClipBoard;
import com.pabble.webnative.Interface.KeyBoardChangeListener;
import com.pabble.webnative.Interface.LifeOs;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;


public class WebActivity extends Activity {
    public static final String TAG = "WebActivity";

    public static WebActivity Instance = null;
    public WebView mWebView;
    private SharedPreferences mSpf;
    private SharedPreferences.Editor mEditor;
    public String downloadFold;

    public Bridge mBridge;
    private DownloadUtil mDownload;

    private String lastLauncherUrl;

    private long lastClickTick = 0;
    private ChromeClient mChromeClient;
    private ProgressBar progressBar;
    private boolean needClear = false;
    protected SoftKeyBoardListener mBoardListener;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.webnative_main);
        progressBar = findViewById(R.id.progressBar);

        mSpf = getSharedPreferences("activity_native", Context.MODE_PRIVATE);
        mEditor = mSpf.edit();
        downloadFold = getFilesDir().getAbsolutePath()+"/download/";
        Instance = this;
        mDownload = new DownloadUtil(this);

        initWebView();
        initDownload();

        mBridge = new Bridge(this,mWebView);

        initInterface();
        initKeyBoard();
    }

    protected void initInterface(){
        mWebView.addJavascriptInterface(new WebViewNative(mBridge), "bridgeNative");
        mWebView.addJavascriptInterface(new FileUtil(), "FileUtil");
        mWebView.addJavascriptInterface(new LifeOs(this),"bridgeOs");
        mWebView.addJavascriptInterface(new ClipBoard(this),"bridgeClip");

    }

    private void initWebView(){
        mWebView = findViewById(R.id.webView);

        WebSettings settings = mWebView.getSettings();
        settings.setDomStorageEnabled(true);
        settings.setJavaScriptEnabled(true);
        settings.setBlockNetworkImage(false);
        settings.setAllowFileAccess(true);
        settings.setAllowContentAccess(true);
        settings.setAllowUniversalAccessFromFileURLs(true);
        settings.setMediaPlaybackRequiresUserGesture(true);
        settings.setJavaScriptCanOpenWindowsAutomatically(true);
        settings.setAllowFileAccessFromFileURLs(true);

        mWebView.setWebViewClient(new WebViewClient() {
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                    view.loadUrl(request.getUrl().toString());
                } else {
                    view.loadUrl(request.toString());
                }
                return true;
            }
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                view.loadUrl(url);
                return true;
            }
            @Override
            @RequiresApi(21)
            @SuppressLint("RestrictedApi")
            public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
                String path = request.getUrl().toString();
//                Log.i(TAG,"path:"+path);
                if(path.startsWith("file://") && path.endsWith(".js")){
                    String path1 = path.replace("file://","");
                    File file = new File(path1);
                    InputStream is = null;
                    try {
                        is = new FileInputStream(file);
                        String mimeType = AssetHelper.guessMimeType(path);
                        return new WebResourceResponse(mimeType, null, is);
                    } catch (FileNotFoundException e) {
                        throw new RuntimeException(e);
                    }
                }
                return null;
            }

            @Override
            @SuppressWarnings("deprecation") // to support API < 21
            public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
                return null;
            }
            @SuppressLint("JavascriptInterface")
            public void onPageStarted(WebView view, String url, Bitmap favicon) {
//                Log.i(TAG,"onPageStarted");
                progressBar.setProgress(0);
                progressBar.setVisibility(View.VISIBLE);
            }
            public void onPageFinished(WebView view, String url) {
//                Log.i(TAG,"onPageFinished:"+url);
                progressBar.setProgress(100);
                progressBar.setVisibility(View.INVISIBLE);
                if(needClear){
                    view.clearHistory();
                    view.clearMatches();
                    needClear = false;
                } else {
                    super.onPageFinished(view,url);
                }
            }
        });
    }

    public void addKeyBoardChangeListener(KeyBoardChangeListener listener){
        if(mBoardListener == null){
            mBoardListener = new SoftKeyBoardListener(this);
        }
        mBoardListener.setKeyBoardChangeListener(listener);
    }

    public void removeKeyBoardChangeListener(KeyBoardChangeListener listener){
        if(mBoardListener != null){
            mBoardListener.setKeyBoardChangeListener(null);
        }
    }

    protected void initKeyBoard(){
        Rect r = new Rect();
        mWebView.getWindowVisibleDisplayFrame(r);

        addKeyBoardChangeListener(new KeyBoardChangeListener() {
            @Override
            public void keyBoardShow(int height) {
                setKeyBoardReSize(true,r.width(),r.height()-height);
            }

            @Override
            public void keyBoardHide(int height) {
                setKeyBoardReSize(false,r.width(),r.height());
            }
        });
    }

    public void setKeyBoardReSize(boolean show,int width,int height){
        ViewGroup.LayoutParams params =  mWebView.getLayoutParams();
        params.width = width;
        params.height = height;
        mWebView.setLayoutParams(params);
    }

    public void setWebChromeClient(ChromeClient client){
        mChromeClient = client;
        client.setProgressBar(progressBar);
        mWebView.setWebChromeClient(client);
    }

    private void initDownload(){
        mWebView.setDownloadListener(new DownloadListener() {
            @Override
            public void onDownloadStart(String url, String userAgent, String contentDisposition, String mimetype, long contentLength) {
                mBridge.callJavascript("download",define.Download_Start+","+url);
                mDownload.download(url, downloadFold, new DownloadUtil.OnDownloadListener() {
                    @Override
                    public void onDownloadSuccess(File file) {
                        mBridge.callJavascript("download",define.Download_Success+","+file.getAbsolutePath());
                    }

                    @Override
                    public void onDownloading(int progress) {
                        mBridge.callJavascript("download",define.Download_Progress+","+progress);
                    }

                    @Override
                    public void onDownloadFailed() {
                        mBridge.callJavascript("download",define.Download_Fail+","+url);
                    }
                });
            }
        });
    }

    public void clearHistroy(){
        needClear = true;
    }
    public void closeCacheFile(){
        mWebView.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE);
    }
    public void launcher(String url){
        this.lastLauncherUrl = url;
        mWebView.setFocusable(true);
        String url1 = mSpf.getString("hot_url",url);
        mWebView.loadUrl(url1);
        clearHistroy();
    }

    public String getWritePath(){
        return this.getFilesDir().getAbsolutePath();
    }

    public void relauncher(){
        if(this.lastLauncherUrl == null){
            Log.i(TAG,"Please use launcher first");
            return;
        }
        String packageName = getPackageName();
        String className = getClass().getName();
        Intent intent = new Intent(Intent.ACTION_MAIN);
        intent.addCategory(Intent.CATEGORY_LAUNCHER);
        ComponentName cn = new ComponentName(packageName, className);
        intent.setComponent(cn);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
        startActivity(intent);
        finish();
    }

    public void setStorage(String key,String value){
        mEditor.putString(key,value);
        mEditor.commit();
    }
    public String getStorage(String key, String def){
        return mSpf.getString(key,def);
    }

    public void showAlert(String title, String ctx,String id){
        Dialog alertDialog = new AlertDialog.Builder(this).
            setTitle(title).
            setMessage(ctx).
            setPositiveButton("确定", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    if(id != "-1"){
                        mBridge.callJavascript("dialog",id+",1");
                    }
                }
            }).
            setNegativeButton("取消", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    if(id != "-1") {
                        mBridge.callJavascript("dialog", id + ",0");
                    }
                }
            }).
            create();
        alertDialog.show();
        alertDialog.setCanceledOnTouchOutside(false);
    }

    public void unzipFile(String path, String fold){
        try{
            mDownload.unzipFile(path, fold, new DownloadUtil.OnUnZipListener() {
                @Override
                public void OnStart(int size) {
                    mBridge.callJavascript("unzip",define.Unzip_Start+","+size);
                }

                @Override
                public void onProgress(int current, int progress) {
                    mBridge.callJavascript("unzip",define.Unzip_Progress+","+progress);
                }

                @Override
                public void onSuccess() {
                    mBridge.callJavascript("unzip",define.Unzip_Success+","+path);
                }

                @Override
                public void onFaild(Error err) {
                    mBridge.callJavascript("unzip",define.Unzip_Fail+","+path);
                }
            });
        }catch (Exception e){
            e.printStackTrace();
            showAlert("解压出错",e.toString(),"-1");
            mBridge.callJavascript("unzip"+define.Unzip_Fail,path);
        }
    }

    // 请求权限回调方法
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);

        switch (requestCode) {
            case Bridge.PERMISSION_REQUEST:
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    mBridge.callJavascript("permission","1");
                } else {
                    mBridge.callJavascript("permission","0");
                }
                break;
        }
    }


    @Override
    protected void onActivityResult(int requestCode,int resultCode, Intent data){
        super.onActivityResult(requestCode,resultCode,data);
        mChromeClient.onActivityResult(requestCode,resultCode,data);

    }
    @Override
    public void onBackPressed(){
        if(mWebView.canGoBack()){
            mWebView.goBack();
        } else if(lastClickTick > System.currentTimeMillis() - 1500){
            onBackActivity();
        } else {
            lastClickTick = System.currentTimeMillis();
            Toast.makeText(WebActivity.this, "再次点击退出", Toast.LENGTH_SHORT).show();
        }
    }

    public void onBackActivity(){
        finish();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if(this.mBoardListener != null){
            this.mBoardListener.setKeyBoardChangeListener(null);
        }
    }
}
